package org.alwayssuper.protocol.commons.transform.realtimev2016;

import org.alwayssuper.protostar.annotation.Field;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.util.List;

/**
 * 2016版可充电储能装置电压数据格式 (0x08)
 * 参考GBT32960协议和ReportDecoder解析规则
 * @author alwaysSuper
 */
@ToString
@Data
@Accessors(chain = true)
public class BatteryVoltageData {
    
    @Field(totalUnit = 1, desc = "可充电储能装置子系统列表")
    private List<ChargeableSubsystemElectric> subsystemList;

    @ToString
    @Data
    @Accessors(chain = true)
    public static class ChargeableSubsystemElectric {
        
        @Field(length = 1, desc = "可充电储能子系统号:1~250")
        private int subsystemNumber;
        
        @Field(length = 2, desc = "可充电储能装置电压:0~5000V,精度0.1V")
        private int voltage;
        
        @Field(length = 2, desc = "可充电储能装置电流:-1000A~+1000A,精度0.1A,偏移1000A")
        private int current;
        
        @Field(length = 2, desc = "单体蓄电池总数:1~65531")
        private int batteryTotalCount;
        
        @Field(length = 2, desc = "本帧起始蓄电池序号:1~65531")
        private int frameStartBatterySeq;
        
        @Field(totalUnit = 1, desc = "单体蓄电池电压列表")
        private List<BatteryVoltage> batteryVoltageList;
        
        // =========================== 传输值与真实值转换方法 ===========================
        
        /**
         * 获取电压值 (V)
         * 传输值范围: 0~10000, 表示 0V~1000V, 精度 0.1V
         * 0xFFFE: 异常, 0xFFFF: 无效
         */
        public double getVoltage() {
            if (voltage == 0xFFFE || voltage == 0xFFFF) {
                return Double.NaN;
            }
            return voltage * 0.1;
        }
        
        /**
         * 设置电压值 (V)
         * 值范围: 0V~1000V
         */
        public void setVoltage(double voltage) {
            if (Double.isNaN(voltage) || voltage < 0 || voltage > 1000.0) {
                this.voltage = 0xFFFF; // 无效
            } else {
                this.voltage = (int) Math.round(voltage * 10);
            }
        }
        
        /**
         * 获取电流值 (A)
         * 传输值范围: 0~20000, 偏移量1000A, 表示 -1000A~+1000A, 精度 0.1A
         * 0xFFFE: 异常, 0xFFFF: 无效
         */
        public double getCurrent() {
            if (current == 0xFFFE || current == 0xFFFF) {
                return Double.NaN;
            }
            return (current - 10000) * 0.1;
        }
        
        /**
         * 设置电流值 (A)
         * 值范围: -1000A~+1000A
         */
        public void setCurrent(double current) {
            if (Double.isNaN(current) || current < -1000.0 || current > 1000.0) {
                this.current = 0xFFFF; // 无效
            } else {
                this.current = (int) Math.round(current * 10 + 10000);
            }
        }
        
        /**
         * 获取单体电池电压列表中对应的电压值
         */
        public double[] getBatteryVoltages() {
            if (batteryVoltageList == null) {
                return new double[0];
            }
            return batteryVoltageList.stream()
                    .mapToDouble(BatteryVoltage::getVoltage)
                    .toArray();
        }
    }
    
    @ToString
    @Data
    @Accessors(chain = true)
    public static class BatteryVoltage {
        
        @Field(length = 2, desc = "单体蓄电池电压:0~15V,精度0.001V")
        private int voltage;
        
        /**
         * 获取单体电池电压值 (V)
         * 传输值范围: 0~60000, 表示 0V~60V, 精度 0.001V
         * 0xFFFE: 异常, 0xFFFF: 无效
         */
        public double getVoltage() {
            if (voltage == 0xFFFE || voltage == 0xFFFF) {
                return Double.NaN;
            }
            return voltage * 0.001;
        }
        
        /**
         * 设置单体电池电压值 (V)
         * 值范围: 0V~60V
         */
        public void setVoltage(double voltage) {
            if (Double.isNaN(voltage) || voltage < 0 || voltage > 60.0) {
                this.voltage = 0xFFFF; // 无效
            } else {
                this.voltage = (int) Math.round(voltage * 1000);
            }
        }
    }
    
    // 通过subsystemList列表长度返回子系统数量
    public int getSubsystemCount() {
        return subsystemList == null ? 0 : subsystemList.size();
    }
}